home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Utilities / byacc 1.8.2 / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-04  |  10.9 KB  |  627 lines  |  [TEXT/R*ch]

  1. #include "defs.h"
  2. #include <signal.h>
  3.  
  4. #ifdef MACINTOSH
  5. #include <console.h>
  6. #endif
  7.  
  8. #define VERSION "Berkeley yacc version 1.8.2 (C or perl)"
  9.  
  10. char dflag;
  11. char lflag;
  12. char rflag;
  13. char tflag;
  14. char vflag;
  15.  
  16. char *myname = PROGRAM;
  17.  
  18. char *file_prefix = "y";
  19. char *temp_form;
  20.  
  21. int prefix_changed = 0;
  22. char *define_prefix = "YY";
  23. char *symbol_prefix = "yy";
  24.  
  25. Language language = C;
  26. char* c_suffixes[] =    { ".code.c",  ".tab.h",  ".tab.c",  ".output" };
  27. char* perl_suffixes[] = { ".code.pl", ".tab.ph", ".tab.pl", ".output" };
  28. char** suffixes = c_suffixes;
  29.  
  30. int lineno;
  31. int outline;
  32.  
  33. char *action_file_name;
  34. char *code_file_name;
  35. char *defines_file_name;
  36. char *input_file_name = "";
  37. char *output_file_name;
  38. char *text_file_name;
  39. char *union_file_name;
  40. char *verbose_file_name;
  41.  
  42. FILE *action_file;    /*  a temp file, used to save actions associated    */
  43.             /*  with rules until the parser is written        */
  44. FILE *code_file;    /*  y.code.c (used when the -r option is specified) */
  45. FILE *defines_file;    /*  y.tab.h                        */
  46. FILE *input_file;    /*  the input file                    */
  47. FILE *output_file;    /*  y.tab.c                        */
  48. FILE *text_file;    /*  a temp file, used to save text until all        */
  49.             /*  symbols have been defined                */
  50. FILE *union_file;    /*  a temp file, used to save the union            */
  51.             /*  definition until all symbol have been        */
  52.             /*  defined                        */
  53. FILE *verbose_file;    /*  y.output                        */
  54.  
  55. int nitems;
  56. int nrules;
  57. int nsyms;
  58. int ntokens;
  59. int nvars;
  60.  
  61. int   start_symbol;
  62. char  **symbol_name;
  63. short *symbol_value;
  64. short *symbol_prec;
  65. char  *symbol_assoc;
  66.  
  67. short *ritem;
  68. short *rlhs;
  69. short *rrhs;
  70. short *rprec;
  71. char  *rassoc;
  72. short **derives;
  73. char *nullable;
  74.  
  75. #ifdef AMIGA
  76. long __near __STKNEED = 1000;
  77. #endif
  78.  
  79. #if __STDC__
  80. extern char *mktemp(char *template);
  81. #else
  82. extern char *mktemp();
  83. #endif
  84.  
  85. #if __STDC__ != 1
  86. extern char *getenv();
  87. #endif
  88.  
  89. #if __STDC__
  90. void done(int k)
  91. #else
  92. void done(k)
  93. int k;
  94. #endif
  95. {
  96.     if (action_file) { fclose(action_file); unlink(action_file_name); }
  97.     if (text_file) { fclose(text_file); unlink(text_file_name); }
  98.     if (union_file) { fclose(union_file); unlink(union_file_name); }
  99.     exit(k);
  100. }
  101.  
  102.  
  103. #if __STDC__
  104. static SIG_TYPE onintr(int junk)
  105. #else
  106. static SIG_TYPE onintr()
  107. #endif
  108. {
  109.     done(1);
  110. }
  111.  
  112.  
  113. #if __STDC__
  114. static void set_signals(void)
  115. #else
  116. static void set_signals()
  117. #endif
  118. {
  119. #ifdef SIGINT
  120.     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
  121.     signal(SIGINT, onintr);
  122. #endif
  123. #ifdef SIGTERM
  124.     if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
  125.     signal(SIGTERM, onintr);
  126. #endif
  127. #ifdef SIGHUP
  128.     if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
  129.     signal(SIGHUP, onintr);
  130. #endif
  131. }
  132.  
  133.  
  134. #if __STDC__
  135. static void usage(void)
  136. #else
  137. static void usage()
  138. #endif
  139. {
  140.     fprintf(stderr,
  141.         "usage: %s [-CPcdlrtv] [-b file_prefix] [-p symbol_prefix] filename\n",
  142.         myname);
  143.     exit(1);
  144. }
  145.  
  146.  
  147. #if __STDC__
  148. static void getargs(int argc, char *argv[])
  149. #else
  150. static void getargs(argc, argv)
  151. int argc;
  152. char *argv[];
  153. #endif
  154. {
  155.     register int i;
  156.     register char *s;
  157.  
  158.     if (argc > 0) myname = argv[0];
  159.  
  160.     s = strrchr(myname, '/');
  161.     if (s == (char *) NULL) {
  162. #ifdef AMIGA
  163.     s = strrchr(myname, ':');
  164.     if (s == (char *) NULL)
  165.         s = myname;
  166.     else
  167.         s++;
  168. #else
  169.     s = myname;
  170. #endif
  171.     }
  172.     else
  173.     s++;
  174.     temp_form = MALLOC(strlen(s) + sizeof(".XXXXXXX"));
  175.     sprintf(temp_form, "%s.XXXXXXX", s);
  176.  
  177.     for (i = 1; i < argc; ++i)
  178.     {
  179.     s = argv[i];
  180.     if (*s != '-') break;
  181.     switch (*++s)
  182.     {
  183.     case '\0':
  184.         input_file = stdin;
  185.         if (i + 1 < argc) usage();
  186.         return;
  187.  
  188.     case '-':
  189.         ++i;
  190.         goto no_more_options;
  191.  
  192.     case 'b':
  193.         if (*++s)
  194.          file_prefix = s;
  195.         else if (++i < argc)
  196.         file_prefix = argv[i];
  197.         else
  198.         usage();
  199.         continue;
  200.  
  201.     case 'c':
  202.     case 'C':
  203.         language = C;
  204.         suffixes = c_suffixes;
  205.         break;
  206.  
  207.     case 'd':
  208.         dflag = 1;
  209.         break;
  210.  
  211.     case 'l':
  212.         lflag = 1;
  213.         break;
  214.  
  215.     case 'p':
  216.         if (*++s)
  217.          symbol_prefix = s;
  218.         else if (++i < argc)
  219.         symbol_prefix = argv[i];
  220.         else
  221.         usage();
  222.         continue;
  223.  
  224.     case 'P':
  225.         language = PERL;
  226.         suffixes = perl_suffixes;
  227.         break;
  228.  
  229.     case 'r':
  230.         rflag = 1;
  231.         break;
  232.  
  233.     case 't':
  234.         tflag = 1;
  235.         break;
  236.  
  237.     case 'v':
  238.         vflag = 1;
  239.         break;
  240.  
  241.     case 'V':
  242.         fprintf(stderr, "%s: %s\n", myname, VERSION);
  243.         exit(1);
  244.  
  245.     default:
  246.         usage();
  247.     }
  248.  
  249.     for (;;)
  250.     {
  251.         switch (*++s)
  252.         {
  253.         case '\0':
  254.         goto end_of_option;
  255.  
  256.         case 'c':
  257.         case 'C':
  258.         language = C;
  259.         suffixes = c_suffixes;
  260.         break;
  261.  
  262.         case 'd':
  263.         dflag = 1;
  264.         break;
  265.  
  266.         case 'l':
  267.         lflag = 1;
  268.         break;
  269.  
  270.         case 'P':
  271.         language = PERL;
  272.         suffixes = perl_suffixes;
  273.         break;
  274.  
  275.         case 'r':
  276.         rflag = 1;
  277.         break;
  278.  
  279.         case 't':
  280.         tflag = 1;
  281.         break;
  282.  
  283.         case 'v':
  284.         vflag = 1;
  285.         break;
  286.  
  287.         case 'V':
  288.         fprintf(stderr, "%s: %s\n", myname, VERSION);
  289.         exit(1);
  290.  
  291.         default:
  292.         usage();
  293.         }
  294.     }
  295. end_of_option:;
  296.     }
  297.  
  298.     if (language == PERL && rflag)
  299.     fprintf(stderr, "%s: Warning: -r not recommended with Perl mode.\n",
  300.         myname);
  301.  
  302. no_more_options:;
  303.     if (i + 1 != argc) usage();
  304.     input_file_name = argv[i];
  305. }
  306.  
  307.  
  308. #if __STDC__
  309. char *allocate(unsigned n)
  310. #else
  311. char *allocate(n)
  312. unsigned n;
  313. #endif
  314. {
  315.     register char *p;
  316.  
  317.     p = NULL;
  318.     if (n)
  319.     {
  320.     p = CALLOC(1, n);
  321.     }
  322.     return (p);
  323. }
  324.  
  325.  
  326. #if __STDC__
  327. char *my_calloc(unsigned k, unsigned n)
  328. #else
  329. char *my_calloc(k, n)
  330. unsigned k;
  331. unsigned n;
  332. #endif
  333. {
  334. #ifndef __STDC__
  335.     extern char *calloc();
  336. #endif
  337.     register char *p;
  338.  
  339.     p = calloc(k, n);
  340.     if (!p) no_space();
  341.     return (p);
  342. }
  343.  
  344.  
  345. #if __STDC__
  346. char *my_malloc(unsigned n)
  347. #else
  348. char *my_malloc(n)
  349. unsigned n;
  350. #endif
  351. {
  352. #ifndef __STDC__
  353.     extern char *malloc();
  354. #endif
  355.     register char *p;
  356.  
  357.     p = malloc(n);
  358.     if (!p) no_space();
  359.     return (p);
  360. }
  361.  
  362.  
  363. #if __STDC__
  364. char *my_realloc(char *p, unsigned n)
  365. #else
  366. char *my_realloc(p, n)
  367. char *p;
  368. unsigned n;
  369. #endif
  370. {
  371. #ifndef __STDC__
  372.     extern char *realloc();
  373. #endif
  374.  
  375.     p = realloc(p, n);
  376.     if (!p) no_space();
  377.     return (p);
  378. }
  379.     
  380.  
  381. #if __STDC__
  382. static void create_file_names(void)
  383. #else
  384. static void create_file_names()
  385. #endif
  386. {
  387.     int i, len;
  388.     char *tmpdir;
  389.  
  390. #ifndef MACINTOSH
  391.  
  392.     tmpdir = getenv("TMPDIR");
  393. #ifdef AMIGA
  394.     if (tmpdir == (char *) NULL) tmpdir = "T:";
  395. #else
  396.     if (tmpdir == (char *) NULL) tmpdir = "/tmp";
  397. #endif /* amiga */
  398.  
  399.     len = strlen(tmpdir);
  400.     i = len + strlen(temp_form) + 1;
  401.  
  402. #ifdef AMIGA
  403.     if (len && tmpdir[len-1] != ':' && tmpdir[len-1] != '/')
  404.     ++i;
  405. #else
  406.     if (len && tmpdir[len-1] != '/')
  407.     ++i;
  408. #endif /* AMIGA */
  409.  
  410. #endif /* MACINTOSH */
  411.  
  412. #ifdef MACINTOSH
  413.     action_file_name = MALLOC(L_tmpnam);
  414.     text_file_name = MALLOC(L_tmpnam);
  415.     union_file_name = MALLOC(L_tmpnam);
  416. #else
  417.     action_file_name = MALLOC(i);
  418.     text_file_name = MALLOC(i);
  419.     union_file_name = MALLOC(i);
  420.  
  421.     strcpy(action_file_name, tmpdir);
  422.     strcpy(text_file_name, tmpdir);
  423.     strcpy(union_file_name, tmpdir);
  424.  
  425. #ifdef AMIGA
  426.     if (len && tmpdir[len-1] != ':' && tmpdir[len - 1] != '/') {
  427.     action_file_name[len] = '/';
  428.     text_file_name[len] = '/';
  429.     union_file_name[len] = '/';
  430.     ++len;
  431.     }
  432. #else
  433.     if (len && tmpdir[len - 1] != '/') {
  434.     action_file_name[len] = '/';
  435.     text_file_name[len] = '/';
  436.     union_file_name[len] = '/';
  437.     ++len;
  438.     }
  439. #endif
  440.  
  441.     strcpy(action_file_name + len, temp_form);
  442.     strcpy(text_file_name + len, temp_form);
  443.     strcpy(union_file_name + len, temp_form);
  444.  
  445.     FREE(temp_form);
  446.     temp_form = (char *) NULL;
  447.  
  448.     action_file_name[len + 5] = 'a';
  449.     text_file_name[len + 5] = 't';
  450.     union_file_name[len + 5] = 'u';
  451.     
  452. #endif /* MACINTOSH, about 39 lines up */
  453.  
  454. #ifdef MACINTOSH
  455.     tmpnam(action_file_name);
  456.     tmpnam(text_file_name);
  457.     tmpnam(union_file_name);
  458. #else
  459.     mktemp(action_file_name);
  460.     mktemp(text_file_name);
  461.     mktemp(union_file_name);
  462. #endif
  463.  
  464.     len = strlen(file_prefix);
  465.  
  466.     output_file_name = MALLOC(len + strlen(suffixes[OUTPUT_SUFFIX]) + 1);
  467.     strcpy(output_file_name, file_prefix);
  468.     strcpy(output_file_name + len, suffixes[OUTPUT_SUFFIX]);
  469.  
  470.     if (rflag)
  471.     {
  472.     code_file_name = MALLOC(len + strlen(suffixes[CODE_SUFFIX]) + 1);
  473.     strcpy(code_file_name, file_prefix);
  474.     strcpy(code_file_name + len, suffixes[CODE_SUFFIX]);
  475.     }
  476.     else
  477.     code_file_name = output_file_name;
  478.  
  479.     if (dflag)
  480.     {
  481.     defines_file_name = MALLOC(len + strlen(suffixes[DEFINES_SUFFIX]) + 1);
  482.     strcpy(defines_file_name, file_prefix);
  483.     strcpy(defines_file_name + len, suffixes[DEFINES_SUFFIX]);
  484.     }
  485.  
  486.     if (vflag)
  487.     {
  488.     verbose_file_name = MALLOC(len + strlen(suffixes[VERBOSE_SUFFIX]) + 1);
  489.     strcpy(verbose_file_name, file_prefix);
  490.     strcpy(verbose_file_name + len, suffixes[VERBOSE_SUFFIX]);
  491.     }
  492. }
  493.  
  494.  
  495. #if __STDC__
  496. static void open_files(void)
  497. #else
  498. static void open_files()
  499. #endif
  500. {
  501.     create_file_names();
  502.  
  503.     if (input_file == 0)
  504.     {
  505.     input_file = fopen(input_file_name, "r");
  506.     if (input_file == 0)
  507.         open_error(input_file_name);
  508.     }
  509.  
  510.     action_file = fopen(action_file_name, "w");
  511.     if (action_file == 0)
  512.     open_error(action_file_name);
  513.  
  514.     text_file = fopen(text_file_name, "w");
  515.     if (text_file == 0)
  516.     open_error(text_file_name);
  517.  
  518.     if (vflag)
  519.     {
  520.     verbose_file = fopen(verbose_file_name, "w");
  521.     if (verbose_file == 0)
  522.         open_error(verbose_file_name);
  523.     }
  524.  
  525.     if (dflag)
  526.     {
  527.     defines_file = fopen(defines_file_name, "w");
  528.     if (defines_file == 0)
  529.         open_error(defines_file_name);
  530.     union_file = fopen(union_file_name, "w");
  531.     if (union_file ==  0)
  532.         open_error(union_file_name);
  533.     }
  534.  
  535.     output_file = fopen(output_file_name, "w");
  536.     if (output_file == 0)
  537.     open_error(output_file_name);
  538.  
  539.     if (rflag)
  540.     {
  541.     code_file = fopen(code_file_name, "w");
  542.     if (code_file == 0)
  543.         open_error(code_file_name);
  544.     }
  545.     else
  546.     code_file = output_file;
  547. }
  548.  
  549.  
  550. #if __STDC__
  551. static void fix_defsym_prefix(void)
  552. #else
  553. static void fix_defsym_prefix()
  554. #endif
  555. {
  556.     char *from;
  557.     int num_lower = 0;
  558.     char *to;
  559.  
  560.     if (strcmp(symbol_prefix, "yy") == 0)
  561.     return;
  562.  
  563.     from = symbol_prefix;
  564.  
  565.     /* check first character for [A-Za-z_] */
  566.     if (!isalpha(*from) && *from != '_') {
  567.     fprintf(stderr,
  568.         "%s: symbol prefix (%s) must start with an underline or letter\n",
  569.         myname, symbol_prefix);
  570.     exit(1);
  571.     }
  572.  
  573.     for (/* void */ ; *from; from++) {
  574.     if (isalnum(*from) || *from == '_') {
  575.         if (islower(*from))
  576.         num_lower++;
  577.     }
  578.     else {
  579.         fprintf(stderr,
  580.             "%s: invalid character (%c) in symbol prefix (%s)\n",
  581.             myname, isgraph(*from) ? *from : '?', symbol_prefix);
  582.         exit(1);
  583.     }
  584.     }
  585.     if (num_lower == 0) {
  586.     fprintf(stderr,
  587.         "%s: symbol prefix (%s) must contain at least 1 lower case character\n",
  588.         myname, symbol_prefix);
  589.     exit(1);
  590.     }
  591.     define_prefix = MALLOC((from - symbol_prefix) + 1);
  592.     for (to = define_prefix, from = symbol_prefix; *from; from++) {
  593.     if (islower(*from))
  594.         *to++ = toupper(*from);
  595.     else
  596.         *to++ = *from;
  597.     }
  598.     *to = *from;
  599.     prefix_changed = 1;
  600. }
  601.  
  602. #if __STDC__
  603. int main(int argc, char *argv[])
  604. #else
  605. int main(argc, argv)
  606. int argc;
  607. char *argv[];
  608. #endif
  609. {
  610.  
  611. #ifdef MACINTOSH
  612.     argc = ccommand(&argv);
  613. #endif /* MACINTOSH */
  614.     set_signals();
  615.     getargs(argc, argv);
  616.     fix_defsym_prefix();
  617.     open_files();
  618.     reader();
  619.     lr0();
  620.     lalr();
  621.     make_parser();
  622.     verbose();
  623.     output();
  624.     done(0);
  625.     /*NOTREACHED*/
  626. }
  627.